<template>
  <div v-loading="!loading" element-loading-text="正在加载..." style="padding: 20px 0">
    <el-row>
      <el-col :lg="{span: 10, offset: 1}">
        <div>
          <video ref="videoRef" style="width: 100%" />
        </div>
        <div v-if="loading">
          <el-button type="primary" icon="Camera" @click="handleShoot">拍照</el-button>
          <el-select v-model="deviceId" @change="checkCamera" placeholder="选择摄像头" style="margin-left: 20px">
            <el-option v-for="(item,index) in devices"
                       :key="index"
                       :label="item.label"
                       :value="item.deviceId"></el-option>
          </el-select>
        </div>
      </el-col>
      <el-col :lg="{span: 11, offset: 1}">
        <div ref="imageBoxRef" class="image-box">
          <el-card
            v-for="(img,index) in imageList"
            :key="index"
            style="width: 360px;margin: 5px;height: 340px"
          >
            <el-image
              :src="img.image"
              :preview-src-list="previewSrcList"
              style="width: 100%"
            ></el-image>
            <template #footer>
              <div style="display: flex;justify-content: space-between">
                <div style="font-size: 12px">拍摄时间：{{ img.time }}</div>
                <div>
                  <el-button type="danger" size="small" @click="del(index)">删除</el-button>
                  <el-button type="primary" size="small" @click="downloadImage(img)">下载</el-button>
                </div>
              </div>
            </template>
          </el-card>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import moment from "moment";
import { download } from "@/utils/image.js";

export default {
  name: "VideoView",
  data() {
    return {
      imageList: [],
      previewSrcList: [],
      loading: false,
      deviceId: "",
      devices: [],
      constraints: {
        audio: false, // 不需要音频
        video: {
          width: { min: 400, ideal: 1871, max: 3742 }, // 3742 摄像头分辨率
          height: { min: 300, ideal: 1403, max: 2806 }, // 2806 摄像头分辨率
          // facingMode: { exact: 'environment' } // 强制后置摄像头
          // facingMode: "user", // 前置摄像头
          deviceId: {} // d1a8fc598d91774f33e064bee23da05023ec4cf2ffc137ae86a270023d96b07d
        }
      }
    };
  },
  mounted() {
    this.initCamera(this.constraints);
  },
  methods: {
    getDevices() {
      const navigator = window.navigator.mediaDevices;
      navigator.enumerateDevices().then(devices => {
        this.devices = devices.filter(f => f.deviceId !== "");
        console.log(this.devices);
      });
    },
    checkCamera() {
      console.log(this.deviceId);
      this.constraints.video.deviceId.exact = this.deviceId;
      this.initCamera(this.constraints);
    },
    initCamera(constraints) {
      const navigator = window.navigator.mediaDevices;
      navigator.getUserMedia(constraints).then(stream => {
        // 用video元素渲染流数据
        if (!this.$refs.videoRef) return;
        this.$refs.videoRef.srcObject = stream;
        this.$refs.videoRef.play();
        this.loading = true;
        this.getDevices();
      }).catch(error => {
        console.log(error);
        this.$message.error("摄像头打不开");
      });
    },
    handleShoot() {
      if (!this.$refs.videoRef || this.$refs.wrapperRef) return;
      // 设置canvas画布
      const canvas = document.createElement("canvas");
      canvas.width = this.$refs.videoRef.videoWidth;
      canvas.height = this.$refs.videoRef.videoHeight;
      // 获取canvas上下文对象
      const ctx = canvas.getContext("2d");
      // 截图操作
      ctx?.drawImage(this.$refs.videoRef, 0, 0, canvas.width, canvas.height);
      // 展示截图
      const image = canvas.toDataURL("image/jpeg");
      const now = new Date();
      const time = moment(now).format("YYYY-MM-DD HH:mm:ss");
      this.previewSrcList.push(image);
      this.imageList.push({ image, time, name: now.getTime() });
      this.scrollToBottom();
    },
    downloadImage(img) {
      download(img.image, img.name);
    },
    del(index) {
      this.imageList.splice(index, 1);
      this.previewSrcList.splice(index, 1);
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const div = this.$refs.imageBoxRef;
        div.scrollTop = div.scrollHeight;
      });
    }
  }
};
</script>

<style scoped>
.image-box {
  display: flex;
  justify-content: left;
  flex-wrap: wrap;
  overflow-y: auto;
  width: 100%;
  height: 720px;
}
</style>
